
local ex_log = require "ex_log"

return function()
    local events = {}
    local M = {}

    function M.attach(e, fn)
        assert(type(fn) == "function", "bad func argument!")
        local fn_map = events[e]
        if not fn_map then
            fn_map = {}
            events[e] = fn_map
        end
        fn_map[fn] = fn
    end

    function M.detach(e, fn)
        assert(type(fn) == "function", "bad func argument!")
        local fn_map = events[e]
        if not fn_map then return end
        fn_map[fn] = nil
    end

    function M.notify(e, ...)
        local fn_map = events[e]
        if not fn_map then return end
        for _, fn in pairs(fn_map) do
            xpcall(fn, ex_log.error, ...)
        end
    end

    function M.clear(e)
        events[e] = nil
    end

    function M.clear_all()
        events = {}
    end

    return M
end
